<?php

namespace app;


use think\Exception;
/**
 * 代理类
 * Class BaseLoader
 * @package app\loader
 */
abstract class BaseLoad
{

    // 当前对象
    private static $_instance = [];
    // 类的实例
    private $_class_instance = [];

    // 该类是否需要初始化
    private $_class_initialize = [];

    // 命名空间
    protected $_namespace = '';
    // 类前缀
    protected $_prefix = '';
    // 类后缀
    protected $_suffix = '';


    /**
     * BaseLoader constructor.
     * @param mixed $arguments
     */
    public function __construct($arguments = null)
    {
        //
        if (empty($this->_namespace)) {

            $class = get_class($this);
            $this->_namespace = dirname($class);
        }
    }


    /**
     * 动态调用函数的接口
     * @param $classname
     * @param $arguments
     * @return mixed
     * @throws Exception
     */
    public static function __callStatic($classname, $arguments)
    {
        // 获取调用者，产生一个单列调用值
        $loader_key = static::class;
        if (!isset(self::$_instance[$loader_key])) {
            self::$_instance[$loader_key] = new static($arguments);
        }

        if (!isset(self::$_instance[$loader_key]->_class_instance[$classname])) {

            // 调用的不是全路径时，生成一个全路径的类名
            if (strpos($classname, '\\') === false) {
                $real_classname = self::$_instance[$loader_key]->_namespace . '\\' .
                    ucfirst(self::$_instance[$loader_key]->_prefix) . ucfirst($classname) . ucfirst(self::$_instance[$loader_key]->_suffix);
            } else {
                $real_classname = $classname;
            }
            if (!class_exists($real_classname)) {
                throw  new Exception($real_classname . ' 未找到');
            }
            //实例化对象
            self::$_instance[$loader_key]->_class_instance[$classname] = new $real_classname();

            // 判断初始是否存在 需要调用初始化
            self::$_instance[$loader_key]->_class_initialize[$classname] = method_exists(self::$_instance[$loader_key]->_class_instance[$classname], '_initilize');
        }

        // 如果类中调用的_initilize 进行调用进行初始化
        if (self::$_instance[$loader_key]->_class_initialize[$classname]) {
            self::$_instance[$loader_key]->_class_instance[$classname]->_initilize($arguments);
        }

        // 返回类对象
        return self::$_instance[$loader_key]->_class_instance[$classname];
    }


}